<script>
import Avatar from './avatar.vue';
import LoadingSpinner from '../../components/loading-spinner.vue';
const timeFormat = require('gitter-web-shared/time/time-format');
const fullTimeFormat = require('gitter-web-shared/time/full-time-format');
const generatePermalink = require('gitter-web-shared/chat/generate-permalink');
const pushState = require('../../../utils/browser/pushState');
const linkDecorator = require('../../../views/chat/decorators/linkDecorator');
import Intersect from './intersect';

export default {
  name: 'ChatItem',
  components: { Avatar, LoadingSpinner, Intersect },
  props: {
    showItemActions: {
      type: Boolean,
      default: false
    },
    message: {
      type: Object,
      required: true
    },
    useCompactStyles: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    sentTimeFormatted: function() {
      return timeFormat(this.message.sent);
    },
    sentTimeFormattedFull: function() {
      return fullTimeFormat(this.message.sent);
    },
    permalinkUrl: function() {
      const troupeUri = this.$store.getters.displayedRoom.uri;
      return generatePermalink(troupeUri, this.message.id, this.message.sent);
    }
  },
  watch: {
    message: function(newMessage, oldMessage) {
      // highlighted is used for bringing users attention to permalinked message
      if (newMessage.highlighted && !oldMessage.highlighted) {
        this.scrollIntoView('smooth', 'center');
      } else if (
        // focusedAt is ensuring this chat item is in view, e.g. when opening TMF we focus on the newest message
        // this condition is met when either the focusedAt property is new, or it has changed
        newMessage.focusedAt &&
        (!oldMessage.focusedAt || newMessage.focusedAt !== oldMessage.focusedAt)
      ) {
        this.scrollIntoView('auto', newMessage.focusedAt.block);
      }
    }
  },
  updated: function() {
    this.decorate();
  },
  mounted: function() {
    // highlighted is used for bringing users attention to permalinked message
    if (this.message.highlighted) this.scrollIntoView('smooth', 'center');
    // focusedAt is ensuring this chat item is in view, e.g. when opening TMF we focus on the newest message
    else if (this.message.focusedAt) this.scrollIntoView('auto', this.message.focusedAt.block);

    // unread items client is not available on the server
    this.unreadItemsClient = require('../../../components/unread-items-client');
    this.decorate();
  },
  methods: {
    setPermalinkLocation: function() {
      pushState(this.permalinkUrl);
    },
    scrollIntoView: function(behavior, block) {
      this.$el.scrollIntoView({ block, behavior });
    },
    decorate: function() {
      linkDecorator.decorate(this);
    },
    onViewportEnter: function() {
      if (this.message.unread) {
        this.unreadItemsClient.markItemRead(this.message.id);
      }
    }
  }
};
</script>

<template>
  <intersect @enter="onViewportEnter()">
    <div
      class="chat-item burstStart"
      :class="{
        compact: useCompactStyles,
        syncerror: message.error,
        unread: message.unread,
        'chat-item__highlighted': message.highlighted
      }"
    >
      <div class="chat-item__container">
        <div class="chat-item__aside">
          <div class="chat-item__avatar">
            <avatar :user="message.fromUser" />
          </div>
        </div>
        <div v-if="showItemActions" class="chat-item__actions">
          <i class="chat-item__icon icon-check chat-item__icon--read"></i>
          <i class="chat-item__icon icon-ellipsis"></i>
        </div>
        <div class="chat-item__content">
          <div class="chat-item__details">
            <div class="chat-item__from">{{ message.fromUser.displayName }}</div>
            <div class="chat-item__username">@{{ message.fromUser.username }}</div>
            <a
              class="chat-item__time"
              :href="permalinkUrl"
              :title="sentTimeFormattedFull"
              @click.stop.prevent="setPermalinkLocation"
              >{{ sentTimeFormatted }}</a
            >
            <loading-spinner v-if="message.loading" class="message-loading-icon" />
          </div>
          <div v-if="message.html" class="chat-item__text" v-html="message.html"></div>
          <div v-else class="chat-item__text">{{ message.text }}</div>
        </div>
      </div>
    </div>
  </intersect>
</template>

<style lang="less" scoped>
@import (reference) 'trp3Vars';
@import (reference) 'trp3Chat';
@import (reference) 'colors';
@import (reference) 'typography';
@import (reference) 'dark-theme';
@import (reference) '../styles/variables';
@import (reference) 'public/js/views/chat/chatItemView.less';

@item-detail-margin: 2px;

.chat-item__details {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  // inspired by https://stackoverflow.com/questions/20626685/better-way-to-set-distance-between-flexbox-items
  margin-left: -@item-detail-margin;
  margin-right: -@item-detail-margin;
}
.chat-item__from,
.chat-item__username,
.chat-item__time {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  margin-left: @item-detail-margin;
  margin-right: @item-detail-margin;
}

.compact .chat-item__container {
  padding-left: 0px;
}

.compact .chat-item__content {
  margin-left: @thread-chat-item-compact-left-margin;
  margin-right: @thread-message-feed-padding;
}

.dark-theme .chat-item__text {
  color: @dark-theme-chat-main-text-color;
}

.message-loading-icon {
  margin: 4px;
}
</style>
